const WebSocket = {
	OPEN:1
}

class Socket{
	constructor(){
		this.baseUrl = `${window.location.protocol === 'https:' ? 'wss' : 'ws'}://${window.location.host}` // 基础URL
		this.webSocketUrl = null // 最终的URL
		this.ws = null // webSocket实例
		this.reconnectTimer = 0 // 重连timer
		this.emitReconnectTimer = 0 // 重连主动触发timer
		this.heartBeatTimer = 0 // 心跳timeId
		this.receiverTimer = 0 // 心跳失效关闭定时器
		this.cacheMessage = [] // 暂存消息
	}
	
	// 初始化ws
	init(url){
		if(url){
			this.webSocketUrl = `${baseUrl}${url}`
		}
		this.ws = new WebSocket(this.webSocketUrl)
		this._bindListeners()
	}
	
	// 手动关闭
	close(){
		if(this.ws){
			this.clearHeartBeat()
			this.ws.close()
		}
	}
	
	// 判断ws是否已连接
	ready(){
		return this.ws && this.ws.readyState == WebSocket.OPEN
	}
	
	// 发送消息
	sendMessage(message){
		if(this.ready()){
			this.ws.send(JSON.stringify(message))
		}else{
			this.cacheMessage.push(message)
		}
	}
	
	// 心跳机制
	heartBeat(){
		this.clearHeartBeat()
		this.heartBeatTimer = setTimeout(() => {
			this.ws.send('ping')
			this.receiverTimer = setTimeout(() => {
				this.close()
			},20000)
		},20000)
	}
	
	// 清理心跳
	clearHeartBeat(){
		if(this.heartBeatTimer){
			clearTimeout(this.heartBeatTimer)
			this.heartBeatTimer = 0
		}
		if(this.receiverTimer){
			clearTimeout(this.receiverTimer)
			this.receiverTimer = 0
		}
	}
	
	// 重连
	reconnect(){
		this.destroyed()
		if(this.reconnectTimer){
			clearTimeout(this.reconnectTimer)
			this.reconnectTimer = 0
		}
		if(this.emitReconnectTimer){
			clearTimeout(this.emitReconnectTimer)
			this.emitReconnectTimer = 0
		}
		
		this.reconnectTimer = setTimeout(() => {
			this.init()
			// 重连后主动触发响应请求
			this.emitReconnectTimer = setTimeout(() => {
				this.$emit('reconnect')
			},1000)
		},2000)
	}
	
	// 监听
	_bindListeners(){
		this.ws.onopen = e => {
			console.log('WebSocket onOpen')
			this.heartBeat()
			if(this.cacheMessage && this.cacheMessage.length){
				this.cacheMessage.forEach(message =>{
					this.sendMessage(message)
				})
			}
		}
		
		this.ws.onmessage = e => {
			if(e.data === 'pong'){
				this.clearHeartBeat()
				this.heartBeat();
			}
			else{
				const data = JSON.parse(e.data)
			}
		}
		
		this.ws.onclose = e => {
			console.log('WebSocket onclose',e)
			this.reconnect()
		}
		
		this.onerror = e => {
			console.log('WebSocket onerror',e)
			this.reconnect()
		}	
	}
	
	destroyed(){
		if(this.ws){
			this.clearHeartBeat()
			this._unbindListeners()
			if(this.ready()){
				this.ws.close()
			}
		}
		this.ws = null
	}
	
	_unbindListeners(){
		this.ws.onopen = null
		this.ws.onmessage = null
		this.ws.onclose = null
		this.ws.onerror = null
	}
	
}

export default new Socket()